<template>
  <div 
    class="drag-upload-area"
    :class="{ 
      'drag-active': isDragActive,
      'drag-disabled': disabled 
    }"
    @dragenter="handleDragEnter"
    @dragover="handleDragOver"
    @dragleave="handleDragLeave"
    @drop="handleDrop"
  >
    <!-- 默认插槽：包裹的内容 -->
    <slot></slot>
    
    <!-- 拖拽提示遮罩 -->
    <div 
      v-if="isDragActive && showOverlay" 
      class="drag-overlay"
      :class="{ 'drag-valid': isDragValid, 'drag-invalid': !isDragValid }"
    >
      <div class="drag-content">
        <el-icon class="drag-icon" :class="{ 'invalid': !isDragValid }">
          <Upload v-if="isDragValid" />
          <CloseBold v-else />
        </el-icon>
        <h3 class="drag-title">
          {{ isDragValid ? dragValidText : dragInvalidText }}
        </h3>
        <p class="drag-description" v-if="isDragValid">
          {{ dragDescription }}
        </p>
        <p class="drag-error" v-else>
          {{ dragErrorMessage }}
        </p>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'
import { ElMessage } from 'element-plus'
import { Upload, CloseBold } from '@element-plus/icons-vue'
import { FILE_SIZE_LIMITS, validateFileSize, validateFileType } from '@/config/upload'

// Props定义
interface Props {
  disabled?: boolean           // 是否禁用拖拽
  accept?: string[]           // 接受的文件类型 ['jpg', 'png', 'pdf']
  maxSize?: number            // 最大文件大小(MB)
  multiple?: boolean          // 是否支持多文件
  uploadPath?: number         // 上传目标文件夹ID
  showOverlay?: boolean       // 是否显示拖拽遮罩
  dragValidText?: string      // 拖拽有效时的提示文本
  dragInvalidText?: string    // 拖拽无效时的提示文本
  dragDescription?: string    // 拖拽描述文本
}

const props = withDefaults(defineProps<Props>(), {
  disabled: false,
  accept: () => [],
  maxSize: FILE_SIZE_LIMITS.MAX_FILE_SIZE / (1024 * 1024), // 使用配置文件中的限制，转换为MB
  multiple: true,
  uploadPath: undefined,
  showOverlay: true,
  dragValidText: '释放开始上传',
  dragInvalidText: '文件类型不支持',
  dragDescription: '支持多文件上传，最大1GB'
})

// Events定义
interface Emits {
  'files-dropped': (files: File[], uploadPath?: number) => void
}

const emit = defineEmits<Emits>()

// 响应式数据
const isDragActive = ref(false)
const isDragValid = ref(true)
const dragCounter = ref(0)
const dragErrorMessage = ref('')

// 检查是否是内部文件移动拖拽
const isInternalFileDrag = (e: DragEvent): boolean => {
  if (!e.dataTransfer) return false

  const types = Array.from(e.dataTransfer.types)
  const effectAllowed = e.dataTransfer.effectAllowed

  console.log('🔍 DragUploadArea 检测拖拽类型:', {
    types,
    effectAllowed,
    hasFiles: types.includes('Files'),
    hasJson: types.includes('application/json'),
    hasText: types.includes('text/plain')
  })

  // 检查effectAllowed是否为move（内部文件移动的特征）
  if (effectAllowed === 'move') {
    console.log('✅ 检测到内部文件移动 (effectAllowed=move)')
    return true
  }

  // 检查是否包含内部文件移动的JSON数据
  const hasInternalFileData = types.includes('application/json')

  // 检查是否有外部文件
  const hasExternalFiles = types.includes('Files')

  // 如果有内部文件数据但没有外部文件，则认为是内部文件移动
  if (hasInternalFileData && !hasExternalFiles) {
    console.log('✅ 检测到内部文件移动 (有JSON数据但无外部文件)')
    return true
  }

  // 检查是否只有text/plain类型（可能是内部拖拽）
  if (types.length === 1 && types.includes('text/plain')) {
    console.log('✅ 检测到内部文件移动 (只有text/plain)')
    return true
  }

  console.log('❌ 检测到外部文件拖拽')
  return false
}

// 处理拖拽进入
const handleDragEnter = (e: DragEvent) => {
  if (props.disabled) return

  // 检查是否是内部文件移动拖拽
  if (isInternalFileDrag(e)) {
    return // 不处理内部文件拖拽，让文件移动逻辑处理
  }

  // 阻止默认行为，但不阻止事件传播
  e.preventDefault()

  dragCounter.value++
  isDragActive.value = true

  // 验证拖拽的文件
  validateDraggedFiles(e)
}

// 处理拖拽悬停
const handleDragOver = (e: DragEvent) => {
  if (props.disabled) return

  // 检查是否是内部文件移动拖拽
  if (isInternalFileDrag(e)) {
    return // 不处理内部文件拖拽，让文件移动逻辑处理
  }

  // 阻止默认行为，但不阻止事件传播
  e.preventDefault()

  if (e.dataTransfer) {
    e.dataTransfer.dropEffect = isDragValid.value ? 'copy' : 'none'
  }
}

// 处理拖拽离开
const handleDragLeave = (e: DragEvent) => {
  if (props.disabled) return

  // 检查是否是内部文件移动拖拽
  if (isInternalFileDrag(e)) {
    return // 不处理内部文件拖拽，让文件移动逻辑处理
  }

  // 阻止默认行为，但不阻止事件传播
  e.preventDefault()

  dragCounter.value--

  if (dragCounter.value === 0) {
    isDragActive.value = false
    isDragValid.value = true
    dragErrorMessage.value = ''
  }
}

// 处理文件拖拽释放
const handleDrop = (e: DragEvent) => {
  if (props.disabled) return

  // 检查是否是内部文件移动拖拽
  if (isInternalFileDrag(e)) {
    return // 不处理内部文件拖拽，让文件移动逻辑处理
  }

  // 阻止默认行为，但不阻止事件传播
  e.preventDefault()

  // 重置状态
  isDragActive.value = false
  isDragValid.value = true
  dragCounter.value = 0
  dragErrorMessage.value = ''

  const files = Array.from(e.dataTransfer?.files || [])

  if (files.length === 0) {
    ElMessage.warning('没有检测到文件')
    return
  }

  // 验证文件
  const validationResult = validateFiles(files)
  if (!validationResult.valid) {
    ElMessage.error(validationResult.message)
    return
  }

  console.log(`📁 拖拽上传 ${files.length} 个文件:`, files.map(f => f.name))

  // 触发文件上传事件
  emit('files-dropped', validationResult.validFiles, props.uploadPath)
}

// 验证拖拽中的文件（预检查）
const validateDraggedFiles = (e: DragEvent) => {
  if (!e.dataTransfer) return

  // 如果是内部文件移动，不进行验证
  if (isInternalFileDrag(e)) {
    return
  }

  const items = Array.from(e.dataTransfer.items || [])

  // 检查是否包含文件
  const hasFiles = items.some(item => item.kind === 'file')
  if (!hasFiles) {
    isDragValid.value = false
    dragErrorMessage.value = '请拖拽文件到此区域'
    return
  }

  // 检查文件数量
  if (!props.multiple && items.length > 1) {
    isDragValid.value = false
    dragErrorMessage.value = '只能上传单个文件'
    return
  }

  isDragValid.value = true
}

// 验证文件（详细检查）
const validateFiles = (files: File[]) => {
  const validFiles: File[] = []
  const errors: string[] = []

  // 检查文件数量
  if (!props.multiple && files.length > 1) {
    return {
      valid: false,
      message: '只能上传单个文件',
      validFiles: []
    }
  }

  for (const file of files) {
    // 使用现有的文件大小验证函数
    const sizeValidation = validateFileSize(file)
    if (!sizeValidation.valid) {
      errors.push(sizeValidation.message!)
      continue
    }

    // 使用现有的文件类型验证函数
    const typeValidation = validateFileType(file)
    if (!typeValidation.valid) {
      errors.push(typeValidation.message!)
      continue
    }

    // 额外的自定义类型检查（如果设置了accept）
    if (props.accept.length > 0) {
      const fileExt = file.name.split('.').pop()?.toLowerCase()
      if (!fileExt || !props.accept.includes(fileExt)) {
        errors.push(`${file.name} 文件类型不在允许列表中`)
        continue
      }
    }

    validFiles.push(file)
  }

  if (errors.length > 0 && validFiles.length === 0) {
    return {
      valid: false,
      message: errors[0],
      validFiles: []
    }
  }

  if (errors.length > 0) {
    console.warn('部分文件验证失败:', errors)
  }

  return {
    valid: validFiles.length > 0,
    message: validFiles.length > 0 ? '' : '没有有效的文件',
    validFiles
  }
}
</script>

<style scoped>
.drag-upload-area {
  position: relative;
  width: 100%;
  height: 100%;
  min-height: 200px;
}

.drag-upload-area.drag-disabled {
  pointer-events: none;
  opacity: 0.6;
}

.drag-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(64, 158, 255, 0.05);
  border: 2px dashed #409eff;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.drag-overlay.drag-invalid {
  background: rgba(245, 108, 108, 0.05);
  border-color: #f56c6c;
}

.drag-content {
  text-align: center;
  padding: 20px;
  color: #409eff;
}

.drag-overlay.drag-invalid .drag-content {
  color: #f56c6c;
}

.drag-icon {
  font-size: 32px;
  margin-bottom: 8px;
}

.drag-icon.invalid {
  color: #f56c6c;
}

.drag-title {
  font-size: 16px;
  font-weight: 500;
  margin: 0 0 4px 0;
}

.drag-description {
  font-size: 14px;
  margin: 0;
  opacity: 0.7;
}

.drag-error {
  font-size: 14px;
  margin: 0;
  color: #f56c6c;
}

/* 移除动画效果，保持简约 */
</style>
